﻿using System;
using System.Threading.Tasks;
using Abp.Authorization;
using Abp.BackgroundJobs;
using Abp.Configuration.Startup;
using Abp.Events.Bus;
using Abp.Json;
using Abp.Runtime.Session;
using Abp.UI;
using Magicodes.WeChat.Application;
using Magicodes.WeChat.Application.BackgroundJob;
using Magicodes.WeChat.Application.Events;
using Magicodes.WeChat.Authorization;
using Magicodes.WeChat.Configuration;
using Magicodes.WeChat.SDK;
using Magicodes.WeChat.SDK.Apis.Menu;
using Magicodes.WeChat.WeChatApiSetting.Dto;
using Newtonsoft.Json;
using Abp.Runtime.Caching;

namespace Magicodes.WeChat.WeChatApiSetting
{
    [AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatApiSetting)]
    public class WeChatApiSettingAppService : AppServiceBase, IWeChatApiSettingAppService
    {
        private readonly IBackgroundJobManager _backgroundJobManager;
        private readonly IMultiTenancyConfig _multiTenancyConfig;
        private readonly IEventBus _eventBus;
        private readonly ICacheManager _cacheManager;

        public WeChatApiSettingAppService(
            IMultiTenancyConfig multiTenancyConfig,
            IBackgroundJobManager backgroundJobManager,
            IEventBus eventBus,
            ICacheManager cacheManager
            )
        {
            _multiTenancyConfig = multiTenancyConfig;
            _backgroundJobManager = backgroundJobManager;
            _eventBus = eventBus;
            _cacheManager = cacheManager;
        }

        /// <summary>
        /// 获取所有设置
        /// </summary>
        /// <returns></returns>
        public virtual async Task<WeChatApiSettingDto> GetAllSettingsAsync()
        {
            var apiSettingValue = await GetSettingValue(WeChatSettings.TenantManagement.WeChatApiSettings);
            var weChatApiSettingEditDto = !string.IsNullOrEmpty(apiSettingValue)
                ? JsonConvert.DeserializeObject<WeChatApiSettingEditDto>(apiSettingValue)
                : null;
            if (weChatApiSettingEditDto != null && string.IsNullOrWhiteSpace(weChatApiSettingEditDto.Token))
                weChatApiSettingEditDto.Token = Guid.NewGuid().ToString("N");

            var payApiSettingValue = await GetSettingValue(WeChatSettings.TenantManagement.WeChatPayApiSettings);

            //var payApiSettingValue = !_multiTenancyConfig.IsEnabled
            //    ? await SettingManager.GetSettingValueAsync(WeChatSettings.TenantManagement.WeChatPayApiSettings)
            //    : await SettingManager.GetSettingValueForTenantAsync(WeChatSettings.TenantManagement.WeChatPayApiSettings,
            //        AbpSession.GetTenantId());

            var weChatPayApiSettingEditDto = !string.IsNullOrEmpty(payApiSettingValue)
                ? JsonConvert.DeserializeObject<WeChatPayApiSettingEditDto>(payApiSettingValue)
                : null;

            return new WeChatApiSettingDto
            {
                WeChatApiSetting = weChatApiSettingEditDto,
                WeChatPayApiSetting = weChatPayApiSettingEditDto
            };
        }

        /// <summary>
        /// 获取微信端自定义菜单设置
        /// </summary>
        /// <returns></returns>
        public async Task<MenuInfo> GetWeChatCustomMenuSettingsAsync()
        {
            var result = WeChatApisContext.Current.MenuApi.Get();
            if (result.ReturnCode == SDK.Apis.ReturnCodes.不存在的菜单数据)
            {
                return new MenuInfo();
            }
            if (!result.IsSuccess()) throw new UserFriendlyException(result.GetFriendlyMessage());
            var apiSettingValue = await GetSettingValue(WeChatSettings.TenantManagement.WeChatCustomMenuSettings);
            if (string.IsNullOrWhiteSpace(apiSettingValue))
                await ChangeSettingValue(WeChatSettings.TenantManagement.WeChatCustomMenuSettings,
                    result.Menu.ToJsonString());
            return result.Menu;
        }

        public virtual async Task UpdateAllSettings(CreateOrUpdateWeChatApiSettingDto input)
        {
            var oldSettings = await GetAllSettingsAsync();
            var apiSetting = new Configuration.WeChatApiSetting
            {
                AppId = input.WeChatApiSetting.AppId,
                AppSecret = input.WeChatApiSetting.AppSecret,
                Token = input.WeChatApiSetting.Token,
                WeiXinAccount = input.WeChatApiSetting.WeiXinAccount
            };
            await ChangeSettingValue(WeChatSettings.TenantManagement.WeChatApiSettings, apiSetting.ToJsonString());

            if (input.WeChatPayApiSetting != null)
            {
                var payApiSetting = new WeChatPayApiSetting
                {
                    CertPassword = input.WeChatPayApiSetting.CertPassword,
                    MchId = input.WeChatPayApiSetting.MchId,
                    Notify = input.WeChatPayApiSetting.Notify,
                    PayCertPath = input.WeChatPayApiSetting.PayCertPath,
                    TenPayKey = input.WeChatPayApiSetting.TenPayKey
                };
                await ChangeSettingValue(WeChatSettings.TenantManagement.WeChatPayApiSettings,
                    payApiSetting.ToJsonString());
            }
            if (input.WeChatApiSetting != null)
            {
                _cacheManager.GetCache("WeChatSetting").Remove(AbpSession.GetTenantId().ToString());
            }

            #region 刷新AccessToken

            //{

            //    if (oldSettings.WeChatApiSetting != null &&
            //        input.WeChatApiSetting.AppId != oldSettings.WeChatApiSetting.AppId ||
            //        input.WeChatApiSetting.AppSecret != oldSettings.WeChatApiSetting.AppSecret)
            //        try
            //        {
            //            WeChatConfigManager.Current.RefreshConfigAndAccessToken(AbpSession.GetTenantId(),
            //                input.WeChatApiSetting);
            //        }
            //        catch (Exception)
            //        {
            //            throw new UserFriendlyException("AppId、密钥存在问题或者IP白名单没有设置！");
            //        }
            //}

            #endregion

            //同步粉丝信息
            _backgroundJobManager.Enqueue<SyncWeChatUsersJob, int?>(_multiTenancyConfig.IsEnabled
                ? AbpSession.GetTenantId()
                : (int?)null);

            //触发设置修改事件
            _eventBus.Trigger(new WeChatApiSettingsUpdatedEventData()
            {
                TenantId = _multiTenancyConfig.IsEnabled
                    ? AbpSession.GetTenantId()
                    : (int?)null,
                WeChatApiSetting = apiSetting
            });
        }

        public async Task UpdateWeChatCustomMenuSettings(MenuInfo input)
        {
            var result = WeChatApisContext.Current.MenuApi.Create(input);
            if (result.IsSuccess())
                await ChangeSettingValue(WeChatSettings.TenantManagement.WeChatCustomMenuSettings,
                    input.ToJsonString());
            throw new UserFriendlyException(result.GetFriendlyMessage());
        }

        private async Task<string> GetSettingValue(string key)
        {
            var apiSettingValue = !_multiTenancyConfig.IsEnabled
                ? await SettingManager.GetSettingValueAsync(key)
                : await SettingManager.GetSettingValueForTenantAsync(key,
                    AbpSession.GetTenantId());
            return apiSettingValue;
        }

        /// <summary>
        ///     更新设置
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private async Task ChangeSettingValue(string key, string value)
        {
            if (_multiTenancyConfig.IsEnabled)
                await SettingManager.ChangeSettingForTenantAsync(AbpSession.GetTenantId(),
                    key, value);
            else
                await SettingManager.ChangeSettingForApplicationAsync(key, value);
        }


    }
}